﻿using System;
using System.Drawing;
using System.Windows.Forms;
using ProjectN.Core.Element;
using ProjectN.Core.Fore;
using ProjectN.Core.Instance;

namespace ProjectN.GUI
{
    public partial class ShowFrame : Form
    {
        private static readonly FrameInfo FRAME_INFO = new FrameInfo(0, 24, 17, 22);

        private IPage page;
        private PageInfo pageInfo;
        private PageRenderer renderer;
        private PageElementSelector selector;

        public ShowFrame()
        {
            InitializeComponent();

            OpenFileDialog.Multiselect = false;
            OpenFileDialog.Title = "打开 ProjectN 笔记文件";
            OpenFileDialog.FilterIndex = 0;
        }

        public IPage Page => this.page ??= this.PageInfo.Page.ToStatic();
        public required PageInfo PageInfo
        {
            get => pageInfo;
            set
            {
                this.pageInfo = value;
                this.Width = Page.Width + FRAME_INFO.ExtX;
                this.Height = Page.Height + FRAME_INFO.ExtY;
                this.TsslFileName.Text = value.Instance.Filename;
                this.TsslItemId.Text = Page.Identity;
                this.Text = string.Format(Properties.Resources.S_TITLE_FORMAT, Page.Identity);

                this.renderer = new PageRenderer(Page,
                    new Action<string>((string status) => { this.Status = status; }),
                    new Action(() => { this.Refresh(); })
                );

                this.selector = new PageElementSelector(Page,
                    new Action<string>((string status) => { this.Status = status; })
                );

                this.ImageDisplay.Image = this.renderer.Image;
                this.ImageDisplay.DisplaySize = this.renderer.Image.Size;
                this.ImageDisplay.FrameInfo = FRAME_INFO;
                this.ImageDisplay.Scaling = 1F;
            }
        }

        public String Status
        {
            get { return this.TsslSatus.Text; }
            private set { this.TsslSatus.Text = value; }
        }

        private void TsmiAbout_Click(object sender, EventArgs e)
        {
            Form aboutBox = new Core.AboutBox();
            aboutBox.Owner = this;
            aboutBox.Show();
        }

        private void RtsmRefresh_Click(object sender, EventArgs e)
        {
            this.renderer.Update();
        }


        private void TsmiScalingOption_Click(object sender, EventArgs e)
        {
            this.GbScaling.Visible = !this.GbScaling.Visible;

        }

        private void TbScaling_ValueChanged(object sender, EventArgs e)
        {
            this.ImageDisplay.Scaling = this.TbScaling.Value / 100F;
            this.ImageDisplay.Refresh();
            this.LbScalingNum.Text = Convert.ToString(this.TbScaling.Value);
        }

        private void ImageDisplay_Click(object sender, EventArgs e)
        {
            Point clicked = ImageDisplay.CursorPositionOnImage;
            int elementId = selector.ClickedElementId(clicked);
            IElement element = this.Page.GetElement(elementId);
            if (element != null)
                element.OnClick(clicked);
        }

        private void TsmiOpenFile_Click(object sender, EventArgs e)
        {
            var result = OpenFileDialog.ShowDialog(this);
            if (result == DialogResult.OK)
            {
                try
                {
                    var instance = Creation.ReadFile(OpenFileDialog.FileName).Value;
                    this.PageInfo = new(instance, instance.MajorPage.Guid);
                }
                catch (Exception exception)
                {
                    this.CreateErrorInfoBox(exception, Properties.Resources.E_OPENFILE_FAILED_TITLE, Properties.Resources.E_OPENFILE_FAILED_MSG);
                }
            }
        }

        private void TsmiShowProperties_Click(object sender, EventArgs e)
        {
            var window = new PropertyEditForm()
            {
                Items = [this.Page],
                Title = "页面属性 - ProjectN"
            };
            window.Show(this);
        }
    }
}
